package com.feidee.data.report.util;

import com.feidee.data.report.constant.Constant;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.security.MessageDigest;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ToolUtils {

    public static final String specialCommonsplitstr = "€";

    public static final String defaultsplitCommon = "\001";

    public static String getNowDay() {
        Date dt = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        return sdf.format(dt);
    }

    public static String getNowHourAndMinute() {
        Date dt = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
        return sdf.format(dt);
    }

    public static String getCurrentDay() {
        Date dt = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        return sdf.format(dt);
    }

    public static String getCurrentDay(long timestamp) {
        Date dt = new Date(timestamp);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        return sdf.format(dt);
    }

    public static String getMonth() {
        Date dt = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        return sdf.format(dt);
    }

    public static String getTimeStr() {
        Date dt = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return sdf.format(dt);
    }

    public static String getTimeStr( long timestamp ) {
        Date dt = new Date(timestamp);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return sdf.format(dt);
    }

    /*
     * 毫秒转化天小时分秒毫秒
     *     Integer ss = 1000;
    Integer mi = ss * 60;
    Integer hh = mi * 60;
    Integer dd = hh * 24;
     */
    public static String getCostTimeStr( Long timestamp ) {
        Integer msToSecondStep = 1000;
        Integer msToMinuteStep = msToSecondStep * 60;
        Integer msToHourStep = msToMinuteStep * 60;
        Integer msToDayStep = msToHourStep * 24;

        Long costDay = timestamp / msToDayStep;
        Long costHour = (timestamp - costDay * msToDayStep) / msToHourStep;
        Long costMinute = (timestamp - costDay * msToDayStep - costHour * msToHourStep) / msToMinuteStep;
        Long costSecond = (timestamp - costDay * msToDayStep - costHour * msToHourStep - costMinute * msToMinuteStep)
                / msToSecondStep;
        Long costMilliSecond = timestamp - costDay * msToDayStep - costHour * msToHourStep
                - costMinute * msToMinuteStep - costSecond * msToSecondStep;

        StringBuffer costStr = new StringBuffer();
        if (costDay >= 0 && costDay < 10) {
            costStr.append(" 0" + costDay + "d");
        } else {
            costStr.append(" " + costDay + "d");
        }

        if (costHour >= 0 && costHour < 10) {
            costStr.append(" 0" + costHour + "h");
        } else {
            costStr.append(" " + costHour + "h");
        }

        if (costMinute >= 0 && costMinute < 10) {
            costStr.append(" 0" + costMinute + "m");
        } else {
            costStr.append(" " + costMinute + "m");
        }

        if (costSecond >= 0 && costSecond < 10) {
            costStr.append(" 0" + costSecond + "s");
        } else {
            costStr.append(" " + costSecond + "s");
        }

        if (costMilliSecond >= 0 && costMilliSecond < 10) {
            costStr.append(" 00" + costMilliSecond + "ms");
        } else if (costMilliSecond >= 10 && costMilliSecond < 100) {
            costStr.append(" 0" + costMilliSecond + "ms");
        } else {
            costStr.append(" " + costMilliSecond + "ms");
        }

        String timeStr = costStr.toString().trim();
        return timeStr;
    }

    // 前端展示耗时格式
    public static String getFrontCostTimeStr( Long timestamp ) {
        Integer msToSecondStep = 1000;
        Integer msToMinuteStep = msToSecondStep * 60;
        Integer msToHourStep = msToMinuteStep * 60;

        Long costHour = timestamp / msToHourStep;
        Long costMinute = (timestamp - costHour * msToHourStep) / msToMinuteStep;
        Long costSecond = (timestamp - costHour * msToHourStep - costMinute * msToMinuteStep) / msToSecondStep;

        StringBuffer costStr = new StringBuffer();
        if (costHour >= 0 && costHour < 10) {
            costStr.append("0" + costHour + ":");
        } else {
            costStr.append(costHour + ":");
        }

        if (costMinute >= 0 && costMinute < 10) {
            costStr.append("0" + costMinute + ":");
        } else {
            costStr.append(costMinute + ":");
        }

        if (costSecond >= 0 && costSecond < 10) {
            costStr.append("0" + costSecond);
        } else {
            costStr.append(costSecond);
        }

        String timeStr = costStr.toString().trim();
        return timeStr;
    }

    public static String replaceBlank( String str ) {
        String dest = "";
        if (str != null) {
            Pattern p = Pattern.compile("\\s|\t|\r|\n");
            Matcher m = p.matcher(str);
            dest = m.replaceAll(" ");
        }
        return dest;
    }

    /**
     * 时间比较
     *
     * @param oldDate
     * @param newDate
     * @return
     */
    public static int compareDatesByCompareTo( String oldDate, String newDate ) {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            Date od = sdf.parse(oldDate);
            Date nd = sdf.parse(newDate);
            return nd.compareTo(od);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return -1;
    }

    /**
     * 获取当前时间的前N天时间
     *
     * @param n
     * @return
     */
    public static String getBeforeDay( int n ) {
        Calendar cl = Calendar.getInstance();
        int nday = cl.get(Calendar.DATE);
        cl.set(Calendar.DATE, nday - n);
        int year = cl.get(Calendar.YEAR);
        int month = cl.get(Calendar.MONTH) + 1;
        int oday = cl.get(Calendar.DATE);
        String cday = year + "-" + month + "-" + oday;
        return cday;
    }

    /**
     * 获取当前时间的前N月时间
     *
     * @param cMonth
     * @return
     */
    public static String getBeforeMonth( String cMonth, int n ) {
        Calendar cal = Calendar.getInstance();
        String cmonth = "";
        try {
            cal.setTime(new SimpleDateFormat("yyyy-MM").parse(cMonth));
            cal.add(Calendar.MONTH, -n + 1);
            int year = cal.get(Calendar.YEAR);
            int month = cal.get(Calendar.MONTH);
            cmonth = year + "-" + (month + 1);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return cmonth;
    }

    public static boolean isNotNull( String str ) {
        if (null == str || "".equals(str) || "null".equals(str)) {
            return Boolean.FALSE;
        }
        return Boolean.TRUE;
    }

    public static boolean isNotRealNull( String str ) {
        if (null == str || "null".equals(str)) {
            return Boolean.FALSE;
        }
        return Boolean.TRUE;
    }

    public static int getYear() {
        Calendar ca = Calendar.getInstance();
        ca.setTime(new java.util.Date());
        int year = ca.get(Calendar.YEAR);
        return year;
    }

    public static boolean isNumeric( String str ) {
        Pattern pattern = Pattern.compile("[0-9]*");
        return pattern.matcher(str).matches();
    }

    public static int getMonths( String startDate ) {
        int result = 0;
        try {
            Calendar c = Calendar.getInstance();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
            int year1 = c.get(Calendar.YEAR);
            int month1 = c.get(Calendar.MONTH);

            c.setTime(sdf.parse(startDate));

            int year2 = c.get(Calendar.YEAR);
            int month2 = c.get(Calendar.MONTH);
            if (year1 == year2) {
                result = month1 - month2;
            } else {
                result = 12 * (year1 - year2) + month1 - month2;
            }

        } catch (ParseException e) {
            e.printStackTrace();
        }
        return result + 1;
    }

    /**
     * 打印时间
     *
     * @param cl
     */
    public static String strCalendar( Calendar cl ) {
        int year = cl.get(Calendar.YEAR);
        int month = cl.get(Calendar.MONTH) + 1;
        int day = cl.get(Calendar.DATE);
        String cday = year + "-" + month + "-" + day;
        return cday;
    }

    public static String getSubString( String s1, String s2 ) {
        if (s1.length() > s2.length()) {
            String temp = s1;
            s1 = s2;
            s2 = temp;
        }
        int n = s1.length();
        int index = 0;
        ok:
        for (; n > 0; n--) {
            for (int i = 0; i < s1.length() - n + 1; i++) {
                String s = s1.substring(i, i + n);
                if (s2.indexOf(s) != -1) {
                    index = i;
                    break ok;
                }
            }
        }
        return s1.substring(index, index + n);
    }

    public static boolean compareTimes( String dateStr1, String dateStr2 ) throws ParseException {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        java.util.Date date1 = null, date2 = null;
        date1 = df.parse(dateStr1);
        date2 = df.parse(dateStr2);
        return date1.getTime() - date2.getTime() >= 0;
    }

    public static long date2long( String date ) throws ParseException {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        java.util.Date dt = df.parse(date);
        return dt.getTime();
    }

    public static Date long2Date( long dateTime ) {
        java.util.Date dt = new Date(dateTime);
        return dt;
    }

    /**
     * 判断是否是时间
     *
     * @param date
     */
    public static boolean isDate( String date ) {
        return isMatch(date, "[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{1}");
    }

    public static boolean isDate( String date, String format ) {
        if ("yyyy-MM-dd".equals(format)) {
            return isMatch(date, "[0-9]{4}-[0-9]{2}-[0-9]{2}");
        }
        return false;
    }

    public static boolean isMatch( String input, String regex ) {
        Matcher matcher = null;
        if (input != null && !input.isEmpty() && regex != null && !regex.isEmpty()) {
            Pattern pattern = Pattern.compile(regex);
            matcher = pattern.matcher(input);
        }
        return matcher != null ? matcher.matches() : false;
    }

    /**
     * 截断字符串两侧的逗号
     *
     * @param str 字符串
     * @return 字符串
     */
    public static String trimComma( String str ) {
        if (str.startsWith(",")) {
            str = str.substring(1);
        }
        if (str.endsWith(",")) {
            str = str.substring(0, str.length() - 1);
        }
        return str;
    }

    /**
     * 使用 Map按value进行排序
     *
     * @param oriMap
     * @return
     */
    public static Map<String, Long> sortMapByValue( Map<String, Long> oriMap ) {
        if (oriMap == null || oriMap.isEmpty()) {
            return null;
        }
        Map<String, Long> sortedMap = new LinkedHashMap<String, Long>();
        List<Map.Entry<String, Long>> entryList = new ArrayList<Map.Entry<String, Long>>(
                oriMap.entrySet());
        //Collections.sort(entryList, new MapValueComparator());
        Collections.sort(entryList, new Comparator<Map.Entry<String, Long>>() {

            @Override
            public int compare( Entry<String, Long> o1, Entry<String, Long> o2 ) {
                // return 0;  // 降序
                return o2.getValue().compareTo(o1.getValue()); // 降序
                //return o1.getValue().compareTo(o2.getValue()); // 升序
            }
        });

        Iterator<Map.Entry<String, Long>> iter = entryList.iterator();
        Map.Entry<String, Long> tmpEntry = null;
        while(iter.hasNext())

        {
            tmpEntry = iter.next();
            sortedMap.put(tmpEntry.getKey(), tmpEntry.getValue());
        }
        return sortedMap;
    }

    /**
     * 获得本机IP
     */
    public static String getHostAddress() {
        try {
            String addr = InetAddress.getLocalHost().getHostAddress();
            return addr;
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
        return "";
    }

    public static String getUuid() {
        return Constant.UUID_IP_PREFIX + UUID.randomUUID().toString().replace("-", "");
    }

    public static String md5(String inStr) {
        MessageDigest md5 = null;
        try {
            md5 = MessageDigest.getInstance("MD5");
        } catch (Exception e) {
            return "";
        }
        char[] charArray = inStr.toCharArray();
        byte[] byteArray = new byte[charArray.length];

        for (int i = 0; i < charArray.length; i++)
            byteArray[i] = (byte) charArray[i];
        byte[] md5Bytes = md5.digest(byteArray);
        StringBuilder hexValue = new StringBuilder();
        for (int i = 0; i < md5Bytes.length; i++) {
            int val = ((int) md5Bytes[i]) & 0xff;
            if (val < 16)
                hexValue.append("0");
            hexValue.append(Integer.toHexString(val));
        }
        return hexValue.toString();
    }

    public static String getPriorityLevel(int priority) {
        String level;
        if (priority < 1) {
            level = "极低";
        } else if (priority == 1) {
            level = "低";
        } else if (priority == 2) {
            level = "中";
        } else if (priority == 3) {
            level = "高";
        } else {
            level = "极高";
        }
        return level;
    }

    public static String replaceWrongAs(String sql) {
        ArrayList<Integer> allAsPosition = new ArrayList<>();
        ArrayList<Integer> replaceAsPosition = new ArrayList<>();
        // 找出所有 as 的位置
        int index = sql.indexOf(" as ");
        while (index != -1) {
            allAsPosition.add(index);
            index = sql.indexOf(" as ", index + 1);
        }
        // 不允许as出现的区域
        HashMap<Integer, Integer> asForbiddenZone = new HashMap<>();
        char[] chars = sql.toCharArray();
        int length = chars.length - 1;
        int count = 0;
        boolean isFirst = true;
        int start = 0, end;
        for (int i = 0; i <= length; i++) {
            char aChar = chars[i];
            if (aChar == '(') {
                if (isFirst) {
                    start = i;
                    isFirst = false;
                }
                count++;
            } else if (aChar == ')') {
                count--;
                if (count == 0) {
                    end = i + 1;
                    asForbiddenZone.put(start, end);
                    isFirst = true;
                }
            }
        }
        Iterator<Map.Entry<Integer, Integer>> iterator = asForbiddenZone.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry<Integer, Integer> next = iterator.next();
            int key = next.getKey();
            int value = next.getValue();
            for (int asPosition : allAsPosition) {
                if (asPosition > key && asPosition < value) {
                    replaceAsPosition.add(asPosition);
                }
            }
        }
        StringBuilder sqlBuilder = new StringBuilder(sql);
        for (int asPosition : replaceAsPosition) {
            sqlBuilder = sqlBuilder.replace(asPosition, asPosition + 4, " As ");
        }
        return sqlBuilder.toString();
    }

    public static String convertStreamToString(InputStream is) {
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        StringBuilder sb = new StringBuilder();

        String line = null;
        try {
            while ((line = reader.readLine()) != null) {
                sb.append(line + "\n");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return sb.toString();
    }

    public static void main( String[] args ) {
        Map<String, Long> stringstringHashMap = new HashMap<String, Long>();
        stringstringHashMap.put("a", 1L);
        stringstringHashMap.put("v", 2L);
        stringstringHashMap.put("g", 5L);
        stringstringHashMap.put("d", 10L);
        stringstringHashMap.put("df", 10L);
        stringstringHashMap = sortMapByValue(stringstringHashMap);
        for (String key : stringstringHashMap.keySet()) {
            System.out.println("key:" + key + "   value:" + stringstringHashMap.get(key));
        }
    }
}
